using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using Microsoft.Ccr.Core;
using Microsoft.Dss.Core.Attributes;
using Microsoft.Dss.Schemas.PartnerListManager;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Dss.ServiceModel.DsspServiceBase;
using Microsoft.Robotics.Services.DepthCamSensor;
using NestedParticleFilter;
using W3C.Soap;
using SubscribeRequestType = Microsoft.Dss.ServiceModel.Dssp.SubscribeRequestType;

namespace MatLocalization
{
    /// <summary>
    /// MatLocalization contract class
    /// </summary>
    public sealed class Contract
    {
        /// <summary>
        /// DSS contract identifer for MatLocalization
        /// </summary>
        [DataMember]
        public const string Identifier = "http://schemas.tempuri.org/2012/03/matlocalization.html";
    }

    /// <summary>
    /// MatLocalization state
    /// </summary>
    [DataContract]
    public class MatLocalizationState
    {
        private bool _matBumperPressed;
        private DateTime _lastPressed;
        private Bitmap _kinectBitmap;
        public Bitmap MatWebcamImage { set; get; }
        private RobotPose _matPose;
        private DateTime _currentKinectReading;
        private DateTime _previousKinectReading;
        private DateTime _lastTimeQueued;

        private DateTime _startDriveTime;
        private DateTime _stopDriveTime;
        
        private int _prevLeftWheelVelocity; // mm/sec
        private int _prevRightWheelVelocity; // mm/sec
        public Bitmap Image { set; get; }
        public DepthCamSensorState DepthState { set; get; }
        public double ObservedDepth { set; get; } // in mm
        public double ObservedAngle { set; get; }  // in degree
        public CustomisedColor ObservedColor { set; get; } // customized RGB color. Average of rgb values observed

        /// <summary>
        /// Default Constructor
        /// </summary>
        public MatLocalizationState()
        {
            _matBumperPressed = false;
            _lastPressed = DateTime.UtcNow;
            _previousKinectReading = DateTime.UtcNow;
            _lastTimeQueued = DateTime.UtcNow;
            _prevRightWheelVelocity = -1;
            _prevLeftWheelVelocity = -1;

        }

        public bool MatBumperPressed
        {
            set { _matBumperPressed = value; }
            get { return _matBumperPressed; }
        }

        public DateTime LastPressed
        {
            set { _lastPressed = value; }
            get { return _lastPressed; }
        }
        public Bitmap KinectBitmap
        {
            set { _kinectBitmap = value; }
            get { return _kinectBitmap; }
        }

        public RobotPose MatPose
        {
            set { _matPose = value; }
            get { return _matPose; }
        }
        public DateTime CurrentKinectReading
        {
            set { _currentKinectReading = value; }
            get { return _currentKinectReading; }
        }
        public DateTime PreviousKinectReading
        {
            set { _previousKinectReading = value; }
            get { return _previousKinectReading; }
        }
        public DateTime LastTimeQueued
        {
            set { _lastTimeQueued = value; }
            get { return _lastTimeQueued; }
        }

        public DateTime StartDriveTime
        {
            set { _startDriveTime = value; }
            get { return _startDriveTime; }
        }
        public DateTime StopDriveTime
        {
            set { _stopDriveTime = value; }
            get { return _stopDriveTime; }
        }
        public int PrevLeftWheelVelocity
        {
            set { _prevLeftWheelVelocity = value; }
            get { return _prevLeftWheelVelocity; }
        }
        public  int PrevRightWheelVelocity
        {
            set { _prevRightWheelVelocity = value; }
            get {return _prevRightWheelVelocity; }
        }
       
    }

    /// <summary>
    /// MatLocalization main operations port
    /// </summary>
    [ServicePort]
    public class MatLocalizationOperations : 
        PortSet<DsspDefaultLookup, 
                DsspDefaultDrop, 
                Get,
                MatExplore,
                UpdateMap,
                Sample,
                Terminate,
                Subscribe>
    {
    }

    public class MatExplore : Update<UpdateRequestType, PortSet<DefaultUpdateResponseType, Fault>>
    {
        public MatExplore()
        {
        }
    }
    public class UpdateMap : Update<UpdateRequestType, PortSet<DefaultUpdateResponseType, Fault>>
    {
        public UpdateMap()
        {

        }
    }
    public class Sample : Update<UpdateRequestType, PortSet<DefaultUpdateResponseType, Fault>>
    {
        public Sample()
        {

        }
    }
    public class Terminate : Update<UpdateRequestType, PortSet<DefaultUpdateResponseType, Fault>>
    {
        public Terminate()
        {

        }
    }
    /// <summary>
    /// MatLocalization get operation
    /// </summary>
    public class Get : Get<GetRequestType, PortSet<MatLocalizationState, Fault>>
    {
        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        public Get()
        {
        }

        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        /// <param name="body">the request message body</param>
        public Get(GetRequestType body)
            : base(body)
        {
        }

        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        /// <param name="body">the request message body</param>
        /// <param name="responsePort">the response port for the request</param>
        public Get(GetRequestType body, PortSet<MatLocalizationState, Fault> responsePort)
            : base(body, responsePort)
        {
        }
    }

    /// <summary>
    /// MatLocalization subscribe operation
    /// </summary>
    public class Subscribe : Subscribe<SubscribeRequestType, PortSet<SubscribeResponseType, Fault>>
    {
        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        public Subscribe()
        {
        }

        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        /// <param name="body">the request message body</param>
        public Subscribe(SubscribeRequestType body)
            : base(body)
        {
        }

        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        /// <param name="body">the request message body</param>
        /// <param name="responsePort">the response port for the request</param>
        public Subscribe(SubscribeRequestType body, PortSet<SubscribeResponseType, Fault> responsePort)
            : base(body, responsePort)
        {
        }
    }
}


